package com.tonyodev.fetchmigrator.fetch1;

import ohos.app.Context;
import ohos.data.rdb.RdbOpenCallback;
import ohos.data.rdb.RdbStore;
import ohos.data.rdb.StoreConfig;
import ohos.data.resultset.ResultSet;

import org.jetbrains.annotations.NotNull;

import java.io.File;

/**
 * 数据库管理类
 *
 * @since 2021-05-24
 */
public class DatabaseHelper extends ohos.data.DatabaseHelper {
    /**
     * id角标
     */
    public static final int INDEX_ID = 0;
    /**
     * COLUMN_URL角标
     */
    public static final int INDEX_COLUMN_URL = 1;
    /**
     * COLUMN_FILEPATH角标
     */
    public static final int INDEX_COLUMN_FILEPATH = 2;
    /**
     * COLUMN_STATUS角标
     */
    public static final int INDEX_COLUMN_STATUS = 3;
    /**
     * COLUMN_HEADERS角标
     */
    public static final int INDEX_COLUMN_HEADERS = 4;
    /**
     * COLUMN_DOWNLOADED_BYTES角标
     */
    public static final int INDEX_COLUMN_DOWNLOADED_BYTES = 5;
    /**
     * COLUMN_FILE_SIZE角标
     */
    public static final int INDEX_COLUMN_FILE_SIZE = 6;
    /**
     * COLUMN_ERROR角标
     */
    public static final int INDEX_COLUMN_ERROR = 7;
    /**
     * COLUMN_PRIORITY角标
     */
    public static final int INDEX_COLUMN_PRIORITY = 8;
    /**
     * 数据库名称
     */
    public static final String DB_NAME = "com_tonyodev_fetch.db";
    private static final int VERSION = 2;
    @NotNull
    private static final String TABLE_NAME = "requests";
    @NotNull
    private static final String COLUMN_ID = "_id";
    @NotNull
    private static final String COLUMN_URL = "_url";
    @NotNull
    private static final String COLUMN_FILEPATH = "_file_path";
    @NotNull
    private static final String COLUMN_STATUS = "_status";
    @NotNull
    private static final String COLUMN_HEADERS = "_headers";
    @NotNull
    private static final String COLUMN_DOWNLOADED_BYTES = "_written_bytes";
    @NotNull
    private static final String COLUMN_FILE_SIZE = "_file_size";
    @NotNull
    private static final String COLUMN_ERROR = "_error";
    @NotNull
    private static final String COLUMN_PRIORITY = "_priority";
    private final Object lock = new Object();
    private RdbStore mStore = null;
    private final RdbOpenCallback callback = new RdbOpenCallback() {
        @Override
        public void onCreate(RdbStore store) {
            store.executeSql("CREATE TABLE " + TABLE_NAME + " ( "
                + COLUMN_ID + " INTEGER PRIMARY KEY NOT NULL, "
                + COLUMN_URL + " TEXT NOT NULL, "
                + COLUMN_FILEPATH + " TEXT NOT NULL, "
                + COLUMN_STATUS + " INTEGER NOT NULL, "
                + COLUMN_HEADERS + " TEXT NOT NULL, "
                + COLUMN_DOWNLOADED_BYTES + " INTEGER NOT NULL, "
                + COLUMN_FILE_SIZE + " INTEGER NOT NULL, "
                + COLUMN_ERROR + " INTEGER NOT NULL, "
                + COLUMN_PRIORITY + " INTEGER NOT NULL, "
                + "unique( " + COLUMN_FILEPATH + " ) )");
        }

        @Override
        public void onUpgrade(RdbStore store, int oldVersion, int newVersion) {
            if (oldVersion == 1) {
                store.executeSql("CREATE UNIQUE INDEX table_unique ON "
                    + TABLE_NAME + " ( " + COLUMN_FILEPATH + ")");
            }
        }
    };

    /**
     * 构造函数
     *
     * @param context 上下文
     */
    public DatabaseHelper(Context context) {
        super(context);
        StoreConfig config = StoreConfig.newDefaultConfig(DB_NAME);
        mStore = getRdbStore(config, VERSION, callback, null);
    }

    /**
     * 获取数据库内容
     *
     * @return 数据集合
     */
    public ResultSet get() {
        synchronized (lock) {
            return mStore.querySql("SELECT * FROM " + TABLE_NAME, null);
        }
    }

    /**
     * 更新数据库_status字段
     */
    public void verifyOK() {
        synchronized (lock) {
            mStore.beginTransaction();
            mStore.executeSql("UPDATE requests SET _status = 900 WHERE _status = 901");
            mStore.markAsCommit();
            mStore.endTransaction();
        }
    }

    /**
     * 清理数据库中过时字段
     */
    public void clean() {
        synchronized (lock) {
            ResultSet resultSet = mStore.querySql("SELECT _id, _file_path FROM requests WHERE _status = 903",
                (String[]) null);
            if (resultSet.getColumnCount() < 1) {
                resultSet.close();
                return;
            }
            mStore.beginTransaction();
            resultSet.goToFirstRow();
            while (!resultSet.isEnded()) {
                String destinationUri = resultSet.getString(resultSet.getColumnIndexForName(COLUMN_FILEPATH));
                if (destinationUri != null && !(new File(destinationUri)).exists()) {
                    long id = resultSet.getLong(resultSet.getColumnIndexForName(COLUMN_ID));
                    mStore.executeSql("UPDATE requests SET _status = 904, _error = -111 WHERE _id = " + id);
                }
                resultSet.goToNextRow();
            }
            mStore.markAsCommit();
            resultSet.close();
            mStore.endTransaction();
        }
    }

    /**
     * 释放数据库句柄
     */
    public void close() {
        if (mStore != null && mStore.isOpen()) {
            mStore.close();
        }
    }
}
